package com.ruoyi.web.web.controller;

import com.ruoyi.system.domain.TST;
import com.ruoyi.web.core.config.AppConf;
import com.ruoyi.accountant.domain.*;
import com.ruoyi.accountant.domain.other.Cashflow;
import com.ruoyi.accountant.domain.other.ProfitLossReport;
import com.ruoyi.accountant.domain.other.ProfitLossReportRow;
import com.ruoyi.accountant.domain.other.StatusResult;
import com.ruoyi.accountant.service.*;
import com.ruoyi.web.web.form.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class PageController {
    @Autowired
    private SettingService settingService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private BalanceService balanceService;

    @Autowired
    private ReasonService reasonService;

    @Autowired
    private TransactionDetailService transactionDetailService;

    @Autowired
    private InaccountService inaccountService;

    @Autowired
    private AccountDetailService accountDetailService;

    @Autowired
    private ReasonDetailService reasonDetailService;

    @Autowired
    private ReportService reportService;

    @Autowired
    private DeviceService deviceService;

    @GetMapping(value={"/index.html", "/"})
    public String index(Model model, HttpSession httpSession) {
        IncomeForm incomeForm = (IncomeForm) httpSession.getAttribute("form");
        if(incomeForm != null) {
            model.addAttribute("form", incomeForm);
            if(incomeForm.getTransactionType().equals("同日收入")) { // 清空凭证日期
                incomeForm.setProofDate(null);
            }
            httpSession.removeAttribute("form");
        } else {
            model.addAttribute("form", new IncomeForm());
        }

        // 查询资金账户
        List<Account> accountList = accountService.findAll();
        //设置
        Setting setting = settingService.findById(AppConf.APP_SETTING_ID);

        List<Reason> reasonList = reasonService.findAllByParent(-1L);

        model.addAttribute("accountList", accountList);
        model.addAttribute("setting", setting);
        model.addAttribute("reasonList", reasonList);

        //当前账户

        return "index.html";
    }

    @GetMapping(value={"/login.html"})
    public String login() {
        return "login.html";
    }

    @GetMapping("/error")
    public String error() {
        return "error.html";
    }

    @GetMapping("/pages/admin/{page}.html")
    public String page(@PathVariable("page") String page) {
        return "pages/admin/"+page;
    }

    @GetMapping("/pages/admin/setting.html")
    public String setting(Model model) {
        Setting setting = settingService.findById(AppConf.APP_SETTING_ID);
        model.addAttribute("setting", setting);
        return "pages/admin/setting";
    }

    @GetMapping("/pages/item/{page}.html")
    public String account(@PathVariable("page") String page) {
        return "pages/item/"+page;
    }

    @GetMapping("/pages/item/account.html")
    public String item_page(Model model) {
        List<Account> accountList = accountService.findAll();
        model.addAttribute("accountList", accountList);
        System.out.println(accountList);
        return "pages/item/account.html";
    }

    @GetMapping("/pages/item/balance.html")
    public String item_balance(Long aid, Model model) {
        List<Balance> balanceList = balanceService.findByAccount(aid);
        System.out.println(balanceList);
        model.addAttribute("balanceList", balanceList);
        return "pages/item/balance";
    }

    @GetMapping("/pages/item/reason.html")
    public String item_reason(Model model) {
        List<Reason> reasonList = reasonService.findAllByParent(-1L);
        model.addAttribute("reasonList", reasonList);

        return "pages/item/reason";
    }

    /****
     * 交易记录明细
     * @param model
     * @return
     */
    @RequestMapping(value = "/pages/detail/transaction.html", method ={RequestMethod.GET, RequestMethod.POST} )
    public String transaction(TransactionDetailListForm transactionDetailListForm, Model model) {

        Validation validate = transactionDetailListForm.validate();
        if(validate.getOk()) {
            // 查询资金账户
            List<Account> accountList = accountService.findAll();
            model.addAttribute("accountList", accountList);


            // 查询记录
            PageInfo<TransactionDetail> page = (PageInfo<TransactionDetail>) transactionDetailService.findAllByForm(transactionDetailListForm);
            System.out.println( page.getList() );
            System.out.println( page );
            model.addAttribute("transactionDetailList", page.getList());
            model.addAttribute("page", page);
            int start = transactionDetailListForm.getPage() > 5 ? transactionDetailListForm.getPage() - 4 : 1;
            model.addAttribute("start", start);
            model.addAttribute("end", page.getTotal() >= (start + 10) ? start+10 : page.getTotal());

            // 查询收支原因
//            List<Reason> reasonList = reasonService.findAllByParent(AppConf.ROOT);
//            model.addAttribute("reasonList", reasonList);
        }

        model.addAttribute("form", transactionDetailListForm);

        return "pages/detail/transaction.html";
    }

    /***
     * 资金账户明细
     * @return
     */
    @GetMapping("/pages/detail/account.html")
    public String account(Model model, AccountDetailForm form) {
        // 查询资金账户
        List<Account> accountList = accountService.findAll();

        Validation validate = form.validate();
        if(validate.getOk()) {
            int start = form.getPage() > 5 ? form.getPage() - 4 : 1;
            PageHelper.startPage(start,form.getRows());
            List<AccountDetail> accountDetails = accountDetailService.findByForm(form);
            PageInfo<AccountDetail> page = new PageInfo<>(accountDetails);
            model.addAttribute("accountList", accountList);
            model.addAttribute("accountDetailList", page.getList());
            model.addAttribute("form", form);
            model.addAttribute("page", page);
            model.addAttribute("start", start);
            model.addAttribute("end", page.getTotal() >= (start + 10) ? start+10 : page.getTotal());
        }

        return "pages/detail/account.html";
    }

    @RequestMapping(value = "/pages/detail/reason.html", method = {RequestMethod.GET, RequestMethod.POST})
    public String reason(ReasonDetailForm form, Model model) {
        // 查询会计项目
        Validation validate = form.validate();
        if(validate.getOk()) {
            PageHelper.startPage(form.getPage()-1, form.getRows(),"createtime desc");
            List<ReasonDetail> details = reasonDetailService.findByForm(form);
            PageInfo<ReasonDetail> reasonDetailPageInfo = new PageInfo<>(details);
            List<Reason> reasonList = reasonService.findAllByParent(-1L);
            System.out.println(reasonDetailPageInfo.getList());
            model.addAttribute("reasonDetailList", reasonDetailPageInfo.getList());
            model.addAttribute("reasonList", reasonList);
            model.addAttribute("form", form);
            model.addAttribute("page", reasonDetailPageInfo);
            int start = form.getPage() > 5 ? form.getPage() - 4 : 1;
            model.addAttribute("start", start);
            model.addAttribute("end", reasonDetailPageInfo.getTotal() >= (start + 10) ? start+10 : reasonDetailPageInfo.getTotal());
        }

        return "pages/detail/reason.html";
    }

    @GetMapping("/pages/detail/deleted.html")
    public String deleted(Model model) {
        List<TransactionDetail> transactionDetailList =  transactionDetailService.findDeleted();
        model.addAttribute("transactionDetailList", transactionDetailList);

        return "pages/detail/deleted";
    }

    /***
     * 报表页
     * @param
     * @return
     */
    @PostMapping("/pages/report")
    public List<TST> report() {

        Map<String,Object> map=new HashMap<>();

        // 营业收入
        List<ProfitLossReportRow> profitRows = reportService.findMonthMoneyCountByTypeAndReason("收入",14L); // 收入
        map.put("profitRows", profitRows);

        fill(profitRows);

        // 营业成本
        List<ProfitLossReportRow> payRows = reportService.findMonthMoneyCountByTypeAndReason("支出", 29L);
        map.put("payRows", payRows);

        fill(payRows);

        // 营业毛利（营业收入 - 营业成本）
        ProfitLossReportRow profitAndPayResult = new ProfitLossReportRow();
        for(int x = 1; x <= 12; x++) {
            List<ProfitLossReport> profit;
            List<ProfitLossReport> pay;

            if(profitRows.size() == 0) {
                profit = new ArrayList<>();
                for(int y = 0; y < 12; y++) {
                    profit.add(new ProfitLossReport(x, new BigDecimal(0), "", new BigDecimal(0)));
                }
            } else {
                profit = profitRows.get(0).getParentData();
            }

            if(payRows.size() == 0) {
                pay = new ArrayList<>();
                for(int y = 0; y < 12; y++) {
                    pay.add(new ProfitLossReport(y+1, new BigDecimal(0), "", new BigDecimal(0)));
                }
            } else {
                pay = payRows.get(0).getParentData();
            }

            ProfitLossReport profitItem = profit.get(x - 1);
            ProfitLossReport payItem = pay.get(x - 1);

            profitAndPayResult.getParentData().add(new ProfitLossReport(profitItem.getMonth(), profitItem.getMoney().subtract(payItem.getMoney()), "", profitItem.getTax()));
        }
        map.put("profitAndPayResult", profitAndPayResult);

        // 营业费用
        List<Reason> subreasonList = reasonService.findById(8L).getSubreasonList();
        List<ProfitLossReportRow> allRow = new ArrayList<>();
        fill(allRow);

        for (Reason reason : subreasonList) {
            List<ProfitLossReportRow> row = reportService.findMonthMoneyCountByTypeAndReason("支出", reason.getRid());
            for (ProfitLossReportRow profitLossReportRow : row) {
                allRow.add(profitLossReportRow);
            }
        }
        map.put("bussinessCost", allRow);

        // 营业损益(营业毛利 － 营业费用)
        ProfitLossReportRow profitAndPayResult2 = new ProfitLossReportRow();
        for(int x = 1; x <= 12; x++) {
            List<ProfitLossReport> profit = profitAndPayResult.getParentData(); //营业毛利

            List<ProfitLossReport> pay; // 营业费用
            if(allRow.size() ==0) {
                pay = new ArrayList<>();
                for(int y = 0; y < 12; y++) {
                    pay.add(new ProfitLossReport(y+1, new BigDecimal(0), "", new BigDecimal(0)));
                }
            } else {
                pay = allRow.get(0).getParentData();
            }

            ProfitLossReport profitItem = profit.get(x - 1);
            ProfitLossReport payItem = pay.get(x - 1);

            profitAndPayResult2.getParentData().add(new ProfitLossReport(profitItem.getMonth(), profitItem.getMoney().subtract(payItem.getMoney()), "", profitItem.getTax()));
        }
        map.put("profitAndPayResult2", profitAndPayResult2);

        // 营业外收益
        List<ProfitLossReportRow> otherRows = reportService.findMonthMoneyCountByTypeAndReason("收入", 15L);
        map.put("otherRows", otherRows);

        //税前损益：(营业损益 + 营业外收益 － 营业外费损)
        ProfitLossReportRow profitAndPayResult3 = new ProfitLossReportRow();
        for(int x = 1; x <= 12; x++) {
            List<ProfitLossReport> profit = profitAndPayResult2.getParentData(); //营业损益
            List<ProfitLossReport> pay; // 营业外收益
            if(otherRows.size() == 0) {
                pay = new ArrayList<>();
                for(int y = 0; y < 12; y++) {
                    pay.add(new ProfitLossReport(y+1, new BigDecimal(0), "", new BigDecimal(0)));
                }
            } else {
                pay = otherRows.get(0).getParentData();
            }

            ProfitLossReport profitItem = profit.get(x - 1);
            ProfitLossReport payItem = pay.get(x - 1);

            profitAndPayResult3.getParentData().add(new ProfitLossReport(profitItem.getMonth(), profitItem.getMoney().add(payItem.getMoney()), "", profitItem.getTax()));
        }
        map.put("profitAndPayResult3", profitAndPayResult3);

        // 税后净利(损)：(税前净利 － 所得税费用)
        ProfitLossReportRow profitAndPayResult4 = new ProfitLossReportRow();
        for(int x = 1; x <= 12; x++) {
            List<ProfitLossReport> profit = profitAndPayResult3.getParentData(); //营业损益

            // 收入的税率
            BigDecimal profitTax = new BigDecimal(0);
            for (ProfitLossReportRow profitRow : profitRows) {
                profitTax = profitTax.add(profitRow.getTaxByMonth(x));
            }

            // 支出的税率
            BigDecimal payTax = new BigDecimal(0);
            for (ProfitLossReportRow rows : payRows) {
                payTax = payTax.add(rows.getTaxByMonth(x));
            }

            BigDecimal countTax = profitTax.add(payTax); // 总税率

            ProfitLossReport profitItem = profit.get(x - 1);

            profitAndPayResult4.getParentData().add(new ProfitLossReport(profitItem.getMonth(), profitItem.getMoney().subtract(countTax), "", profitItem.getTax()));
        }
        map.put("profitAndPayResult4", profitAndPayResult4);
        List<TST> tstList=new ArrayList<>();
        //税前损益：(营业损益 + 营业外收益 － 营业外费损)
        TST SQSY=new TST();
        SQSY.setId(7L);
        SQSY.setName("营业损益(营业毛利 － 营业费用)");
        for(ProfitLossReport i:profitAndPayResult.getParentData()){
            if(i.getMonth()==1){
                SQSY.setMonth1(i.getMoney());
            }
            if(i.getMonth()==2){
                SQSY.setMonth2(i.getMoney());
            }
            if(i.getMonth()==3){
                SQSY.setMonth3(i.getMoney());
            }
            if(i.getMonth()==4){
                SQSY.setMonth4(i.getMoney());
            }
            if(i.getMonth()==5){
                SQSY.setMonth5(i.getMoney());
            }
            if(i.getMonth()==6){
                SQSY.setMonth6(i.getMoney());
            }
            if(i.getMonth()==7){
                SQSY.setMonth7(i.getMoney());
            }
            if(i.getMonth()==8){
                SQSY.setMonth8(i.getMoney());
            }
            if(i.getMonth()==9){
                SQSY.setMonth9(i.getMoney());
            }
            if(i.getMonth()==10){
                SQSY.setMonth10(i.getMoney());
            }
            if(i.getMonth()==11){
                SQSY.setMonth11(i.getMoney());
            }
            if(i.getMonth()==12){
                SQSY.setMonth12(i.getMoney());
            }
        }

        tstList.add(SQSY);

        //税后损益：(税前损益 － 所得税费用)
        TST SHSY=new TST();
        SHSY.setId(8L);
        SHSY.setName("税后损益：(税前损益 － 所得税费用)");
        tstList.add(SHSY);

        //综合损益总额：(税后损益 + 其他综合损益)
        TST ZHSY=new TST();
        ZHSY.setId(9L);
        ZHSY.setName("综合损益总额：(税后损益 + 其他综合损益)");
        tstList.add(ZHSY);

        return tstList;
    }

    /***
     * 如果数据不存在则填充
     * @param profitRows
     */
    private void fill(List<ProfitLossReportRow> profitRows) {
        if(profitRows.size() == 0) {
            ProfitLossReportRow profitLossReportRow = new ProfitLossReportRow();
            profitLossReportRow.setCount(new BigDecimal(0));

            List<ProfitLossReport> parentData = new ArrayList<>(); //所有具体原因的12个月报告
            for(int y = 0; y < 12; y++) {
                parentData.add(new ProfitLossReport(y+1, new BigDecimal(0), "", new BigDecimal(0)));
            }
            profitLossReportRow.setParentData(parentData);

            profitLossReportRow.setParentCount(new BigDecimal(0));

            profitRows.add(profitLossReportRow);
        }
    }

    /***
     * 现金流
     * @param
     * @return
     */
    @PostMapping("/pages/report/cashflow")
    @ResponseBody
    public Map<String,Object> cashflow(CashFlowForm form) {
        // 根据时间区间查询账户余额

        Map<String,Object> map=new HashMap<>();
        if(form.getStart()!=null) {
            Cashflow cashflow = reportService.findCashFlow(form);
            map.put("cashflow", cashflow);
        }

        return map;
    }

    /***
     * 财务状况表（应收款和应付款的数值）
     * @param
     * @return
     */
    @ResponseBody
    @PostMapping("/pages/report/status")
    public Map<String,Object> status(StatusForm form) {
        Map<String,Object> map=new HashMap<>();
        StatusResult result;
        if(form.getType().equals("reason")) {
            result = reportService.findStatusByReason(form);
        } else { // 查询账户
            result = reportService.findStatusByAccount(form);
        }
        map.put("result", result);
        map.put("form", form);

        return map;
    }

    @GetMapping("/pages/report/device.html")
    public String device(Model model) {
        List<Device> deviceList = deviceService.findAll();
        model.addAttribute("deviceList", deviceList);
        return "pages/report/device.html";
    }
}
